package yu.liu.personal.app.myapplication.utils.adapters;

import android.content.Context;
import android.content.Intent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import yu.liu.personal.app.myapplication.components.items.AVGListChildItem;
import yu.liu.personal.app.myapplication.components.items.AVGListGroupItem;
import yu.liu.personal.app.myapplication.components.views.AnimatedExpandableListView;
import yu.liu.personal.app.myapplication.components.views.CalculatorPanelPopupWindow;
import yu.liu.personal.app.myapplication.models.AVGItem;
import yu.liu.personal.app.myapplication.models.AssistConstants;
import yu.liu.personal.app.myapplication.utils.ResourceManager;

/**
 * Created by Administrator on 2016/9/25.
 */

public class AVGListAdapter
        extends AnimatedExpandableListView.AnimatedExpandableListAdapter {

    public final static int COMPARE_STATUS_IDLE = 0;
    public final static int COMPARE_STATUS_SELECTION = 1;
    public final static int COMPARE_STATUS_AVAILABLE = 2;
    private int compareSelectCounter;

    private Context resContext;
    private ResourceManager resManager;

    private List<AVGItem> avgItems;
    private List<AVGItem> searchItems;
    private List<AVGItem> filterItems;

    private List<Boolean> cachedTypeChecks;
    private List<Boolean> cachedStarChecks;
    private List<Boolean> cachedConsumeChecks;

    private HashMap<String, Integer> typeMap;
    private int compareSelectStatus;
    private List<AVGItem> selectItems;

    private final int lowConsumeLimit = 10;
    private final int midConsumeLimit = 20;

    public AVGListAdapter(Context context) {
        resContext = context;
        resManager = ResourceManager.getManager(resContext);
        typeMap = new HashMap<>();
        typeMap.put("格斗", 0);
        typeMap.put("重击", 1);
        typeMap.put("强攻", 2);
        typeMap.put("爆轰", 3);
        typeMap.put("突袭", 4);
        typeMap.put("狙击", 5);
        compareSelectCounter = 0;
        compareSelectStatus = COMPARE_STATUS_IDLE;
        selectItems = new ArrayList<>();
    }

    public void setAvgItems(List<AVGItem> avgItems) {
        this.avgItems = avgItems;
        find("");
    }

    @Override
    public int getGroupCount() {
        return filterItems == null ? 0 : filterItems.size();
    }

//    @Override
//    public int getChildrenCount(int groupPosition) {
//        return avgItems == null?0:(groupPosition >= avgItems.size()?0:1);
//    }

    @Override
    public Object getGroup(int groupPosition) {
        return filterItems.get(groupPosition);
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return filterItems.get(groupPosition);
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
                             ViewGroup parent) {
        AVGListGroupItem group;
        if (convertView == null) {
            group = new AVGListGroupItem(resContext);
            group.initView(null, resManager
                    .getResourceID("layout", "layout_fragment_avg_list_group_item"));
            convertView = group.getContentView();
            convertView.setTag(group);
        } else {
            group = (AVGListGroupItem) convertView.getTag();
        }
        AVGItem item = (AVGItem) getGroup(groupPosition);
        group.setItem(item);
        group.updateViews();
        return convertView;
    }

    @Override
    public View getRealChildView(int groupPosition, int childPosition,
                                 boolean isLastChild, View convertView,
                                 ViewGroup parent) {
        AVGListChildItem child;
        if (convertView == null) {
            child = new AVGListChildItem(resContext);
            child.initView(null, resManager
                    .getResourceID("layout", "layout_fragment_avg_list_child_item"));
            convertView = child.getContentView();
            convertView.setTag(child);
        } else {
            child = (AVGListChildItem) convertView.getTag();
        }
        AVGItem item = (AVGItem) getChild(groupPosition, childPosition);
        child.setItem(item);
        child.updateViews();
        return convertView;
    }

    @Override
    public int getRealChildrenCount(int groupPosition) {
        return avgItems == null ? 0 : (groupPosition >= avgItems.size() ? 0 : 1);
    }

//    @Override
//    public View getChildView(int groupPosition, int childPosition, boolean
// isLastChild, View convertView, ViewGroup parent) {
//        AVGListChildItem child;
//        if(convertView == null) {
//            child = new AVGListChildItem(resContext);
//            child.initView(null, resManager.getResourceID("layout",
// "layout_fragment_avg_list_child_item"));
//            convertView = child.getContentView();
//            convertView.setTag(child);
//        } else {
//            child = (AVGListChildItem) convertView.getTag();
//        }
//        AVGItem item = (AVGItem) getChild(groupPosition, childPosition);
//        child.setItem(item);
//        child.updateViews();
//        return convertView;
//    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }

    public int getCompareSelectCounter() {
        return compareSelectCounter;
    }

    public AVGItem selectOrUnselectGroupForComp(int position) {
        AVGItem select = (AVGItem) getGroup(position);
        if(select != null) {
            if(select.selected && compareSelectCounter > 0) {
                select.selected = false;
                compareSelectCounter--;
                selectItems.remove(select);
            } else if(!select.selected && compareSelectCounter < 3){
                select.selected = true;
                compareSelectCounter++;
                selectItems.add(select);
            } else {
                select = null;
            }
        }
        if(compareSelectCounter > 1 && compareSelectCounter < 4) {
            compareSelectStatus = COMPARE_STATUS_AVAILABLE;
        } else {
            compareSelectStatus = COMPARE_STATUS_SELECTION;
        }
        return select;
    }

    public int getCompareSelectStatus() {
        return compareSelectStatus;
    }

    public void enterSelectionMode() {
        compareSelectStatus = COMPARE_STATUS_SELECTION;
    }

    public void quitSelectionMode() {
        compareSelectStatus = COMPARE_STATUS_IDLE;
        compareSelectCounter = 0;
        for(AVGItem item : selectItems) {
            item.selected = false;
        }
        selectItems.clear();
    }

    public List<AVGItem> getSelectItems() {
        return selectItems;
    }

    private int getCount() {
        return avgItems == null ? 0 : avgItems.size();
    }

    private void getIntersection() {
        for(int i = 0; i < (filterItems == null ? 0 : filterItems.size()); i++) {
            AVGItem item = filterItems.get(i);
            if(!searchItems.contains(item)) {
                filterItems.remove(item);
                i--;
            }
        }
    }

    public void filterTheList(List<Boolean> typeList, List<Boolean> starList,
                              List<Boolean> consumeList) {
        if (filterItems == null) {
            filterItems = new ArrayList<>();
        } else {
            filterItems.clear();
        }
        if (typeList != null && starList != null && consumeList != null) {
            // start filter
            for (int i = 0; i < getCount(); i++) {
                AVGItem item = avgItems.get(i);
                boolean con_1 = false;
                boolean con_2 = false;
                boolean con_3 = false;
                if (typeMap.containsKey(item.type)) {
                    int index = typeMap.get(item.type);
                    if (typeList.get(index)) {
                        con_1 = true;
                    }
                }
                if (starList.get((item.stars - 1))) {
                    con_2 = true;
                }
                if (consumeList.get(0)) {
                    if (item.oilConsume <= lowConsumeLimit &&
                        item.ammoConsume <= lowConsumeLimit) {
                        con_3 = true;
                    }
                }
                if (consumeList.get(1)) {
                    if ((item.oilConsume > lowConsumeLimit &&
                        item.oilConsume <= midConsumeLimit) ||
                        (item.ammoConsume > lowConsumeLimit &&
                        item.ammoConsume <= midConsumeLimit)) {
                        con_3 = true;
                    }
                }
                if (consumeList.get(2)) {
                    if (item.oilConsume > midConsumeLimit &&
                        item.ammoConsume > midConsumeLimit) {
                        con_3 = true;
                    }
                }
                if(con_1 && con_2 && con_3) {
                    filterItems.add(item);
                }
            }
        } else {
            for (int i = 0; i < getCount(); i++) {
                filterItems.add(avgItems.get(i));
            }
        }
        cachedTypeChecks = typeList;
        cachedStarChecks = starList;
        cachedConsumeChecks = consumeList;
        getIntersection();
    }

    public void findBest(int type) {
        if (searchItems == null) {
            searchItems = new ArrayList<>();
        } else {
            searchItems.clear();
        }
        int index = -1;
        int max = 0;
        for(int i = 0; i < getCount(); i++) {
            AVGItem item = avgItems.get(i);
            switch (type) {
                case AssistConstants.SEARCH_TYPE_HP:
                    if(item.hp > max) {
                        max = item.hp;
                        index = i;
                    }
                    break;
                case AssistConstants.SEARCH_TYPE_SHIELD:
                    if(item.shield > max) {
                        max = item.shield;
                        index = i;
                    }
                    break;
                case AssistConstants.SEARCH_TYPE_ARMOR:
                    if(item.armor > max) {
                        max = item.armor;
                        index = i;
                    }
                    break;
                case AssistConstants.SEARCH_TYPE_RESIST:
                    if(item.resist > max) {
                        max = item.resist;
                        index = i;
                    }
                    break;
                case AssistConstants.SEARCH_TYPE_ATK:
                    if(item.atk > max) {
                        max = item.atk;
                        index = i;
                    }
                    break;
                case AssistConstants.SEARCH_TYPE_SCOUT:
                    if(item.scout > max) {
                        max = item.scout;
                        index = i;
                    }
                    break;
                case AssistConstants.SEARCH_TYPE_SPD:
                    if(item.spd > max) {
                        max = item.spd;
                        index = i;
                    }
                    break;
                case AssistConstants.SEARCH_TYPE_OIL:
                    if(item.oilConsume > max) {
                        max = item.oilConsume;
                        index = i;
                    }
                    break;
                case AssistConstants.SEARCH_TYPE_AMMO:
                    if(item.ammoConsume > max) {
                        max = item.ammoConsume;
                        index = i;
                    }
                    break;
                default:
                    break;
            }
        }
        if(index >= 0) {
            searchItems.add(avgItems.get(index));
        }
        filterTheList(cachedTypeChecks, cachedStarChecks, cachedConsumeChecks);
    }

    public void find(String name) {
        if (searchItems == null) {
            searchItems = new ArrayList<>();
        } else {
            searchItems.clear();
        }
        for(int i = 0; i < getCount(); i++) {
            AVGItem item = avgItems.get(i);
            if(item.name.contains(name)) {
                searchItems.add(item);
            }
        }
        filterTheList(cachedTypeChecks, cachedStarChecks, cachedConsumeChecks);
    }
}
